import React, { CSSProperties, ReactNode } from 'react'
import styled from 'styled-components'
import { RTColumn, SortItem, SortOrder } from '../type/interfaces'
import { transform } from '../helpers/transform'

interface SortIconProps {
  style?: CSSProperties
  className?: string
  size?: number
  order?: SortOrder
  onClick?(e: React.MouseEvent): void
}

function SortIcon({ size = 32, style, className, order, onClick }: SortIconProps) {
  return (
    <svg
      style={style}
      className={className}
      focusable="false"
      preserveAspectRatio="xMidYMid meet"
      width={size}
      height={size}
      viewBox="0 0 32 32"
      aria-hidden="true"
      onClick={onClick}
    >
      <path fill={order === 'asc' ? '#23A3FF' : '#bfbfbf'} transform="translate(0, 4)" d="M8 8L16 0 24 8z" />
      <path fill={order === 'desc' ? '#23A3FF' : '#bfbfbf'} transform="translate(0, -4)" d="M24 24L16 32 8 24z " />
    </svg>
  )
}

function DefaultSortHeaderCell({
  children,
  column,
  onToggle,
  sortOrder,
  clickArea,
}: SortHeaderCellProps) {
  // 通过 justify-content 来与 col.align 保持对齐方向一致
  const justifyContent = column.align === 'right' ? 'flex-end' : column.align === 'center' ? 'center' : 'flex-start'

  return (
    <TableHeaderCell
      onClick={clickArea === 'content' ? onToggle : undefined}
      style={{
        justifyContent,
        cursor: clickArea === 'content' ? 'pointer' : undefined,
      }}
    >
      {children}
      <SortIcon
        onClick={clickArea === 'icon' ? onToggle : undefined}
        style={{
          userSelect: 'none',
          marginLeft: 2,
          flexShrink: 0,
          cursor: clickArea === 'icon' ? 'pointer' : undefined,
        }}
        size={16}
        order={sortOrder}
      />
    </TableHeaderCell>
  )
}

const TableHeaderCell = styled.div`
  display: flex;
  align-items: center;
`

export interface SortHeaderCellProps {
  /** 调用 makeSortTransform(...) 时的参数 */
  sortOptions: Required<Omit<SortFeatureOptions, 'SortHeaderCell' | 'defaultSorts'>>

  /** 在添加排序相关的内容之前 表头原有的渲染内容 */
  children: ReactNode

  /** 当前排序 */
  sortOrder: SortOrder

  /** 多列排序下，sortIndex 指明了当前排序字段起作用的顺序. 当 sortOrder 为 none 时，sortIndex 固定为 -1 */
  sortIndex: number

  /** 当前列的配置 */
  column: RTColumn

  /** 切换排序的回调 */
  onToggle(e: React.MouseEvent): void

  /** 点击事件的响应区域 */
  clickArea: 'content' | 'icon'
}

export interface SortFeatureOptions {
  /** (非受控) 默认的排序字段列表 */
  defaultSorts?: SortItem[]

  /** (受控) 排序字段列表 */
  sorts?: SortItem[]

  /** 更新排序字段列表的回调函数 */
  onChangeSorts?(nextSorts: SortItem[]): void

  /** 排序切换顺序 */
  orders?: SortOrder[]

  /** 自定义排序表头 */
  SortHeaderCell?: React.ComponentType<SortHeaderCellProps>

  /** 是否对触发 onChangeOpenKeys 的 click 事件调用 event.stopPropagation() */
  stopClickEventPropagation?: boolean

  /** 点击事件的响应区域，默认为 content */
  clickArea?: 'content' | 'icon'
}


export function sort(opts: SortFeatureOptions = {}) {
  return function sortStep(columns: any[]) {
    const {
      orders = ['desc', 'asc', 'none'],
      SortHeaderCell = DefaultSortHeaderCell,
      stopClickEventPropagation,
      clickArea = 'content',
    } = opts

    const inputSorts =  opts.sorts ?? opts.defaultSorts ?? []
    const activeSorts = inputSorts.filter((s) => s.order !== 'none')
   
    const sorts =  activeSorts

    const onChangeSorts = (nextSorts: SortItem[]) => {
      opts.onChangeSorts?.(nextSorts)
    }

    const sortOptions: SortHeaderCellProps['sortOptions'] = {
      sorts,
      onChangeSorts,
      orders,
      stopClickEventPropagation,
      clickArea,
    }

    const sortMap = new Map(sorts.map((sort, index) => [sort.code, { index, ...sort }]))


    return processColumns(columns)

    // 在「升序 - 降序 - 不排序」之间不断切换
    function toggle(code: string) {
      const sort = sortMap.get(code)
      if (sort == null) {
        onChangeSorts(sorts.concat([{ code, order: orders[0] }]))
      } else {
        const index = sorts.findIndex((s) => s.code === code)
        const nextSorts = sorts.slice(0, index + 1)
        const nextOrder = getNextOrder(sort.order)
        if (nextOrder === 'none') {
          nextSorts.pop()
        } else {
          nextSorts[index] = { ...nextSorts[index], order: nextOrder }
        }
        onChangeSorts(nextSorts)
      }
    }

    function processColumns(columns: RTColumn[]) {
      return columns.map(dfs)

      function dfs(col: RTColumn): RTColumn {
        const result = { ...col }

        const sortable = col.code && (col?.sortable || sortMap.has(col.code))
        const active = sortable && sortMap.has(col.code)

        if (sortable) {
          let sortIndex = -1
          let sortOrder: SortOrder = 'none'

          if (active) {
            const { order, index } = sortMap.get(col.code)
            sortOrder = order
            sortIndex = index

          }

          result.title = (
            <SortHeaderCell
              clickArea={clickArea}
              onToggle={(e) => {
                if (stopClickEventPropagation) {
                  e.stopPropagation()
                }
                toggle(col.code)
              }}
              sortOrder={sortOrder}
              column={col}
              sortIndex={sortIndex}
              sortOptions={sortOptions}
            >
              {transform.safeRenderHeader(col)}
            </SortHeaderCell>
          )
        }

        return result
      }
    }

    function getNextOrder(order: SortOrder) {
      const idx = orders.indexOf(order)
      return orders[idx === orders.length - 1 ? 0 : idx + 1]
    }
  }
}
